#pragma once

#include "bitmap.h"
#include "imageclass_decl.h"

namespace g2 
{
  template <class C>
  class p2p_matcher;

  template <class C>
  class p2l_matcher;
} //namespace g2

namespace img 
{

template <typename R> struct pyramid;

/// given transform that being applied to point of frame0 produces corresponding point of frame1;
/// the function computes and returns root-mean-square divergence beetwen masked pixels;
/// later it updates the transformation;
/// only pixels of frame0 with not-zero alpha component take part in the computations
/// with the weight proportional to the value in alpha (simply speaking mask0 is in frame0.a);
/// std::numeric_limits<float>::max() return value means error
/// M here is either g2::p2p_matcher or g2::p2l_matcher
template <template <class U> class M, class T>
float calc_flow(T & transform, const byte_image & frame0, const byte_image & frame1);

/// the same but updates the transformation first starting from the highest level (with lowest resolution),
/// then descending until original resolution, makes specified number of iterations for each pyramid level,
/// returns divergence just before the last iteration
template <template <class U> class M, class T>
float calc_flow_pyramid(T & transform, const pyramid<byte_image> & frame0, const pyramid<byte_image> & frame1,
                int iters_per_level);

} //namespace img
